import inspect
from abc import ABC
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from fastmcp import FastMCP

from prowler_mcp_server.lib.logger import logger
from prowler_mcp_server.prowler_app.utils.api_client import ProwlerAPIClient


class BaseTool(ABC):
    """Abstract base class for all MCP tools.

    This class defines the contract that all domain-specific tools must follow.
    It ensures consistency across tool registration and provides common utilities.

    Key responsibilities:
    - Enforce implementation of register_tools() via ABC
    - Provide shared access to API client and logger
    - Define common patterns for tool registration
    - Support dependency injection for the FastMCP instance

    Attributes:
        _api_client: Singleton instance of ProwlerAPIClient for API requests
        _logger: Logger instance for structured logging

    Example:
        class FindingsTools(BaseTool):
            def register_tools(self, mcp: FastMCP) -> None:
                mcp.tool(self.search_security_findings)
                mcp.tool(self.get_finding_details)

            async def search_security_findings(self, severity: list[str] = Field(...)):
                # Implementation with access to self.api_client
                response = await self.api_client.get("/api/v1/findings")
                return response
    """

    def __init__(self):
        """Initialize the tool.

        Sets up shared dependencies that all tools can access:
        - API client (singleton) for making authenticated requests
        - Logger instance for structured logging
        """
        self._api_client = ProwlerAPIClient()
        self._logger = logger

    @property
    def api_client(self) -> ProwlerAPIClient:
        """Get the shared API client instance.

        Returns:
            Singleton instance of ProwlerAPIClient for making API requests
        """
        return self._api_client

    @property
    def logger(self):
        """Get the logger instance.

        Returns:
            Logger instance for structured logging
        """
        return self._logger

    def register_tools(self, mcp: "FastMCP") -> None:
        """Automatically register all public async methods as tools with FastMCP.

        This method inspects the subclass and automatically registers all public
        async methods (not starting with '_') as tools. Subclasses do not need
        to override this method.

        Args:
            mcp: The FastMCP instance to register tools with
        """
        # Get all methods from the subclass
        registered_count = 0

        for name, method in inspect.getmembers(self, predicate=inspect.ismethod):
            # Skip private/protected methods
            if name.startswith("_"):
                continue

            # Skip methods inherited from BaseTool
            if name in ["register_tools"]:
                continue

            # Skip property getters
            if name in ["api_client", "logger"]:
                continue

            # Check if the method is a coroutine function (async)
            if inspect.iscoroutinefunction(method):
                mcp.tool(method)
                registered_count += 1
                self.logger.debug(f"Auto-registered tool: {name}")

        self.logger.info(
            f"Auto-registered {registered_count} tools from {self.__class__.__name__}"
        )
